/**
 * Project Name:Micro-Services-Config-API
 * File Name   :Config.java
 * Package Name:com.micro.services.config
 * Date:2015-9-7上午9:15:05
 * Copyright (c) 2015, http://my.oschina.net/httpssl All Rights Reserved.
 *
*/

package com.micro.services.config;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;

import com.micro.services.common.utils.CollectionUtils;
import com.micro.services.common.utils.ReflectUtils;
import com.micro.services.common.utils.StringUtils;

public abstract class Config implements Serializable {
	
	
	protected abstract void checkConfig();
	
	/** 
	*/
	private static final long serialVersionUID = 2584710526619285504L;

	/**
	 * 在这个类中定义所有解析要用到的正则表达式
	 * 
	 * @param <T>
	 */

	public <T> Object parseValue(Class<T> type, String value) {
		if (type == char.class || type == Character.class) {
			return value.length() > 0 ? value.charAt(0) : '\0';
		} else if (type == boolean.class || type == Boolean.class) {
			return Boolean.valueOf(value);
		} else if (type == byte.class || type == Byte.class) {
			return Byte.valueOf(value);
		} else if (type == short.class || type == Short.class) {
			return Short.valueOf(value);
		} else if (type == int.class || type == Integer.class) {
			return Integer.valueOf(value);
		} else if (type == long.class || type == Long.class) {
			return Long.valueOf(value);
		} else if (type == float.class || type == Float.class) {
			return Float.valueOf(value);
		} else if (type == double.class || type == Double.class) {
			return Double.valueOf(value);
		}
		return value;
	}

	protected String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String toString() {
        StringBuilder buf = new StringBuilder();
//        buf.append(getTagName(getClass()));
        Method[] methods = getClass().getMethods();
        for (Method method : methods) {
            try {
                String name = method.getName();
                //只取得get和is方法.取属性的值的方法
                if ((name.startsWith("get") || name.startsWith("is")) 
                        && ! "getClass".equals(name) && ! "get".equals(name) && ! "is".equals(name)
                        && Modifier.isPublic(method.getModifiers()) 
                        && method.getParameterTypes().length == 0
                        && ReflectUtils.isPrimitive(method.getReturnType())) {
                    int i = name.startsWith("get") ? 3 : 2;
                    String key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
                    Object value = method.invoke(this, new Object[0]);
                    if (value != null) {
                        buf.append(" ");
                        buf.append(key);
                        buf.append("=\"");
                        buf.append(value);
                        buf.append("\"");
                    }
                }
            } catch (Exception e) {
//               
            }
        }
		return buf.toString();
	}
	 
	protected void appendAnnotation(Class<?> annotationClass, Object annotation) {
		Method[] methods = annotationClass.getMethods();
		for (Method method : methods) {
			if (method.getDeclaringClass() != Object.class && method.getReturnType() != void.class
					&& method.getParameterTypes().length == 0 && Modifier.isPublic(method.getModifiers())
					&& !Modifier.isStatic(method.getModifiers())) {
				try {
					String property = method.getName();
					if ("interfaceClass".equals(property) || "interfaceName".equals(property)) {
						property = "interface";
					}
					String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
					Object value = method.invoke(annotation, new Object[0]);
					if (value != null && !value.equals(method.getDefaultValue())) {
						Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType());
						if ("filter".equals(property) || "listener".equals(property)) {
							parameterType = String.class;
							value = StringUtils.join((String[]) value, ",");
						} else if ("parameters".equals(property)) {
							parameterType = Map.class;
							value = CollectionUtils.toStringMap((String[]) value);
						}
						try {
							Method setterMethod = getClass().getMethod(setter, new Class<?>[] { parameterType });
							setterMethod.invoke(this, new Object[] { value });
						} catch (NoSuchMethodException e) {
							// ignore
						}
					}
				} catch (Throwable e) {

				}
			}
		}
	}
	
	
}